package com.zrrd.jt_admin.manager.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zrrd.jt_admin.common.bo.RoleBo;
import com.zrrd.jt_admin.common.bo.RuleBo;
import com.zrrd.jt_admin.common.entity.Manager;
import com.zrrd.jt_admin.common.entity.Role;
import com.zrrd.jt_admin.common.entity.Rule;
import com.zrrd.jt_admin.common.vo.ManagerPageVo;
import com.zrrd.jt_admin.common.vo.ManagerLoginVo;
import com.zrrd.jt_admin.common.vo.ManagerVo;
import com.zrrd.jt_admin.manager.mapper.ManagerMapper;
import com.zrrd.jt_admin.manager.service.ManagerService;
import com.zrrd.jt_admin.manager.service.RoleService;
import com.zrrd.jt_admin.manager.service.RuleService;
import com.zrrd.jt_admin.common.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.sql.Time;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ZhangYK
 * @version 8.0
 * @title ManagerServiceImpl
 * @description
 * @create 2024/6/25 20:14
 */
@Service
@Slf4j
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, Manager> implements ManagerService {

    private final String TOKEN = "TOKEN_";

    @Resource
    private ManagerMapper managerMapper;

    @Resource
    private RoleService roleService;

    @Resource
    private RuleService ruleService;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 将token存入redis,并设置过期时间为1天
     * @param token
     */
    public void saveToken(String token,Integer userId) {
        redisTemplate.opsForValue().set(TOKEN+userId, token,1, TimeUnit.DAYS);
        log.error(token);
    }

    /**
     * 管理员账号登录
     *
     * @param username 用户名
     * @param password 密码
     * @return 管理员的整体信息
     */
    @Override
    public ManagerLoginVo login(String username, String password) {

        //分3步
        //1-根据用户名查询manager表，
        Manager manager = managerMapper.getManagerByUsername(username);
        //2-判断查询到的密码和用户输入的密码是否一致，不一致直接return
        if (manager == null) {
            return null;
        }
        //给password进行加密
        ///*******加密------
        //将从Controller层传入的password进行MD5加密
        //加密--  加盐加密  盐：
        String pwd = DigestUtils.md5DigestAsHex((password + JwtUtils.generalKey()).getBytes());
        if (!manager.getPassword().equals(pwd)) {
            return null;
        }
        //3-如果密码一致，说明登录成功，需要返回角色信息以及角色的权限列表
        ManagerLoginVo managerLoginVo = new ManagerLoginVo();
        //4-根据manager查到的角色id role_id。查询角色表，将查询到的角色信息，封装成Role对象，赋值给ManagerVo的role属性
        Role role = roleService.getById(manager.getRoleId());
        managerLoginVo.setRole(role);
        //5-根据roleid查询当前角色对应的权限菜单列表，并且复制给ManagerVo的tree属性
        List<RuleBo> tree = ruleService.getRuleListByRoleId(manager.getRoleId());
        managerLoginVo.setTree(tree);
        //6-遍历权限菜单列表，拿出所有的菜单名称，封装成新的列表，并且复制给ManagerVo的ruleNames属性
        managerLoginVo.setId(manager.getId());
        managerLoginVo.setStatus(manager.getStatus());
        managerLoginVo.setUsername(manager.getUsername());
        managerLoginVo.setAvatar(manager.getAvatar());
        managerLoginVo.setRoleId(manager.getRoleId());
        managerLoginVo.setIsSuper(manager.getIsSuper());
        managerLoginVo.setCreateTime(manager.getCreateTime());
        managerLoginVo.setUpdateTime(manager.getUpdateTime());
        //token
        String token = JwtUtils.getToken((long) manager.getId());
        managerLoginVo.setToken(token);

        //将token放入redis缓存中
        saveToken(token,manager.getId());

        //菜单项名称
        List<String> ruleNames = new ArrayList<>();
        for (Rule rule : tree) {
            if (rule.getRuleId()!=0){
                ruleNames.add(rule.getName());
            }
        }
        managerLoginVo.setRuleNames(ruleNames);
        return managerLoginVo;
    }

    /**
     * 分页查询所有管理员信息
     *
     * @param page
     * @param limit
     * @param keyword
     * @return
     */
    @Override
    public ManagerPageVo findByPage(Integer page, Integer limit, String keyword) {
        //1-查询管理员信息列表
        //List<Manager> managerList = managerMapper.getManagerList();
        List<ManagerVo> managerVoList = new ArrayList<>();
        //设置pageHelper分页
        PageHelper.startPage(page,limit);
        //判断搜索关键字是否为null
        boolean blank = StringUtils.isNotBlank(keyword);
        List<Manager> managerList = lambdaQuery()
                .like(blank, Manager::getUsername, keyword)
                .list();
        //把查询到的集合放入pageInfo
        PageInfo pageInfo = new PageInfo(managerList);


        //2-遍历管理员信息列表，根据每个管理员信息role_id查询该管理员的角色信息
        //3-将管理员信息和管理员的角色信息都封装进ManagerVo对象，再形成ManagerVo对象的集合
        for (Manager manager : managerList) {
            Role role = roleService.getById(manager.getRoleId());
//            managerVoList.add(new ManagerVo(manager.getId(),manager.getStatus(),manager.getUsername(),
//                    manager.getAvatar(),manager.getRoleId(),manager.getIsSuper(),manager.getCreateTime(),
//                    manager.getUpdateTime(), role));
            ManagerVo managerVo = new ManagerVo();
            BeanUtils.copyProperties(manager,managerVo);
            managerVo.setRole(role);
            managerVoList.add(managerVo);
        }
        //4-将ManagerVo对象的集合封装进封装进ManagerPageVo的list属性
        ManagerPageVo managerPageVo = new ManagerPageVo();
        managerPageVo.setList(managerVoList);
        //5-计算查询到的管理员信息列表长度，封装进ManagerPageVo的totalCount属性
        managerPageVo.setTotalCount(pageInfo.getTotal());
        //6-查询角色列表，封装进ManagerPageVo的totalCount属性roles
        List<Role> roleList = roleService.list();
        List<RoleBo> roles = roleList.stream().map(role -> {
            RoleBo roleBo = new RoleBo();
            BeanUtils.copyProperties(role,roleBo);
            return roleBo;
        }).collect(Collectors.toList());
        managerPageVo.setRoles(roles);
        //7-返回ManagerPageVo
        return managerPageVo;
    }




}
